/**
 * @file gtkArbre.c
 * @brief Fichier source du module gtkAjout.
 *
 * @author Rachid Delory, Mamadou Keita, Florian Bernard
 */

/* *********************************************************************

                       Librairies de gtkArbre

********************************************************************* */

#include "gtkArbre.h"

/* *********************************************************************

                        Fonctions                                      

********************************************************************* */

void toggledVue(GtkCellRendererToggle *cell_renderer, gchar *gpath, gpointer user_data)
{
  GtkTreePath * path = gtk_tree_path_new_from_string(gpath);
  GtkArbre *gArbre = user_data;
  GtkTreeIter iter;
  int id;
  int type;
  gboolean b;

  if(path)
    {
      gtk_tree_model_get_iter (GTK_TREE_MODEL(gArbre->store), &iter, path);
      gtk_tree_path_free (path);

      gtk_tree_model_get (GTK_TREE_MODEL(gArbre->store), &iter,
			  ID_COLUMN, &id,
			  TYPE_COLUMN, &type,
			  VUE_COLUMN, &b, 
			  -1);
      gtk_tree_store_set(gArbre->store, &iter, VUE_COLUMN, !b, -1);
      if(type == REGROUPEMENT_OEU)
	{
	  Arbre * arb;
	  arb = recupSousArbreId_Arb(gArbre->arbre, id);
	  setVue_DReg(arb, !b ? 1 : 0);
	}
      else
	{
	  Oeuvre *oeuvre = recupSousFeuilleId_Arb(gArbre->arbre, id);
	  if(oeuvre)
	    {
	      setVue_DOeu(oeuvre, !b ? 1 : 0);
	    }
	}
    }
  (void)cell_renderer;
}

GtkArbre * creer_GArb(GtkInfo *ginfo)
{
  GtkArbre *gArbre;
  GtkTreeViewColumn *column;
  GtkCellRenderer *renderer;
  GtkTreeSelection *select;
  gArbre = (GtkArbre *) malloc ( 1 * sizeof(GtkArbre));
  /* Creation de l'arbre */
  gArbre->arbre = creer_Arb(NULL);
  gArbre->gInfo = ginfo;
  recuperation_DReg(gArbre->arbre, 0, 1);
  recuperation_DOeu(gArbre->arbre, 0);
  /*  recuperation_DOeu(arbre, 0);*/
  /* Create a model.  We are using the store model for now, though we
   * could use any other GtkTreeModel */
  gArbre->store = gtk_tree_store_new (N_COLUMNS,
				      G_TYPE_BOOLEAN,
				      GDK_TYPE_PIXBUF,
				      G_TYPE_STRING,
				      G_TYPE_STRING,
				      G_TYPE_STRING,
				      G_TYPE_STRING,
				      G_TYPE_STRING,
				      G_TYPE_INT,
				      G_TYPE_STRING,
				      G_TYPE_INT,
				      G_TYPE_INT,
				      G_TYPE_INT);

  /* Create a view */
  gArbre->gArbre = gtk_tree_view_new_with_model (GTK_TREE_MODEL (gArbre->store));
  /* custom function to fill the model with data */
  recuperation_Arbre_GArb(gArbre->store, gArbre->arbre, NULL, 1);

  /* Create a cell render and arbitrarily make it red for demonstration
   * purposes */
  
  renderer = gtk_cell_renderer_toggle_new ();
  /*
  g_object_set (G_OBJECT (renderer),
		"foreground", "red",
		NULL);
  */
  /* Create a column, associating the "text" attribute of the
   * cell_renderer to the first column of the model */
  column = gtk_tree_view_column_new_with_attributes (" ", renderer,
						     "active", VUE_COLUMN,
						     NULL);
  g_signal_connect(renderer, "toggled", G_CALLBACK(toggledVue), gArbre);
  /* Add the column to the view. */
  gtk_tree_view_append_column (GTK_TREE_VIEW (gArbre->gArbre), column);

  /* Illustration */
  renderer = gtk_cell_renderer_pixbuf_new ();
  column = gtk_tree_view_column_new_with_attributes (" ",
						     renderer,
						     "pixbuf", ILLUSTRATION_COLUMN,
						     NULL);
  /* The column is resizable */
  gtk_tree_view_column_set_resizable (GTK_TREE_VIEW_COLUMN(column), TRUE);
  gtk_tree_view_append_column (GTK_TREE_VIEW (gArbre->gArbre), column);

  /* Titre */
  renderer = gtk_cell_renderer_text_new ();
  column = gtk_tree_view_column_new_with_attributes ("Titre",
						     renderer,
						     "text", TITRE_COLUMN,
						     NULL);
  gtk_tree_view_column_set_resizable (GTK_TREE_VIEW_COLUMN(column), TRUE);
  gtk_tree_view_append_column (GTK_TREE_VIEW (gArbre->gArbre), column);

  /* Genre */
  /*
  renderer = gtk_cell_renderer_text_new ();
  column = gtk_tree_view_column_new_with_attributes ("Genre",
						     renderer,
						     "text", GENRE_COLUMN,
						     NULL);
  gtk_tree_view_column_set_resizable (GTK_TREE_VIEW_COLUMN(column), TRUE);
   gtk_tree_view_append_column (GTK_TREE_VIEW (gArbre->gArbre), column);
  */
  /* Editeur */
  /*
  renderer = gtk_cell_renderer_text_new ();
  column = gtk_tree_view_column_new_with_attributes ("Editeur",
						     renderer,
						     "text", EDITEUR_COLUMN,
						     NULL);
  gtk_tree_view_column_set_resizable (GTK_TREE_VIEW_COLUMN(column), TRUE);
  gtk_tree_view_append_column (GTK_TREE_VIEW (gArbre->gArbre), column);
  */
  /* Realisateur */
  /*
  renderer = gtk_cell_renderer_text_new ();
  column = gtk_tree_view_column_new_with_attributes ("Réalisateur",
						     renderer,
						     "text", REALISATEUR_COLUMN,
						     NULL);
  gtk_tree_view_column_set_resizable (GTK_TREE_VIEW_COLUMN(column), TRUE);
  gtk_tree_view_append_column (GTK_TREE_VIEW (gArbre->gArbre), column);
  */
  /* Metrage */
  /*
  renderer = gtk_cell_renderer_text_new ();
  column = gtk_tree_view_column_new_with_attributes ("Métrage",
						     renderer,
						     "text", METRAGE_COLUMN,
						     NULL);
  gtk_tree_view_column_set_resizable (GTK_TREE_VIEW_COLUMN(column), TRUE);
  gtk_tree_view_append_column (GTK_TREE_VIEW (gArbre->gArbre), column);
  */
  /* NOTEPERSO */
  /*
  renderer = gtk_cell_renderer_spinner_new ();
  column = gtk_tree_view_column_new_with_attributes ("Note",
						     renderer,
						     "pulse", NOTEPERSO_COLUMN,
						     NULL);
  gtk_tree_view_column_set_resizable (GTK_TREE_VIEW_COLUMN(column), TRUE);
  gtk_tree_view_append_column (GTK_TREE_VIEW (gArbre->gArbre), column);
  */
  /* Date */
  /*
  renderer = gtk_cell_renderer_text_new ();
  column = gtk_tree_view_column_new_with_attributes ("Date de sortie",
						     renderer,
						     "text", DATE_COLUMN,
						     NULL);
  gtk_tree_view_column_set_resizable (GTK_TREE_VIEW_COLUMN(column), TRUE);
  gtk_tree_view_append_column (GTK_TREE_VIEW (gArbre->gArbre), column);
  */
  /* Type */
  /*
  renderer = gtk_cell_renderer_text_new ();
  column = gtk_tree_view_column_new_with_attributes ("Type",
						     renderer,
						     "text", TYPE_COLUMN,
						     NULL);
  gtk_tree_view_column_set_resizable (GTK_TREE_VIEW_COLUMN(column), TRUE);
  gtk_tree_view_append_column (GTK_TREE_VIEW (gArbre->gArbre), column);
  */
  /* ID */
  /*
  renderer = gtk_cell_renderer_text_new ();
  column = gtk_tree_view_column_new_with_attributes ("ID",
						     renderer,
						     "text", ID_COLUMN,
						     NULL);
  gtk_tree_view_column_set_resizable (GTK_TREE_VIEW_COLUMN(column), TRUE);
  gtk_tree_view_append_column (GTK_TREE_VIEW (gArbre->gArbre), column);
  */
  /* Last column.. Arbre (adresse de l'arbre) */
  /*
  renderer = gtk_cell_renderer_text_new ();
  column = gtk_tree_view_column_new_with_attributes ("ARBRE",
						     renderer,
						     "text", ARBRE_COLUMN,
						     NULL);
 
  gtk_tree_view_column_set_resizable (GTK_TREE_VIEW_COLUMN(column), TRUE);
  gtk_tree_view_append_column (GTK_TREE_VIEW (gArbre->gArbre), column);
  */
  /* The column can be clicked by the user */
  gtk_tree_view_set_headers_clickable(GTK_TREE_VIEW(gArbre->gArbre), TRUE);

  /* Setup the selection handler */
  select = gtk_tree_view_get_selection (GTK_TREE_VIEW (gArbre->gArbre));
  gtk_tree_selection_set_mode (select, GTK_SELECTION_SINGLE);

  g_signal_connect (G_OBJECT (select), "changed",
		    G_CALLBACK (tree_selection_changed_cb),
		    gArbre);
  
  /* Set the different callback function */
  g_signal_connect(gArbre->gArbre, "row-expanded", G_CALLBACK(expanded), gArbre);

  g_signal_connect(gArbre->gArbre, "row-collapsed", G_CALLBACK(collapsed), gArbre);

  /* Create a scroll widget to resize the tree */
  gArbre->scroll = gtk_scrolled_window_new(NULL, NULL);
  gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(gArbre->scroll), gArbre->gArbre);
  return gArbre;
}

void tree_selection_changed_cb(GtkTreeSelection *selection, gpointer data)
{
  GtkTreeIter iter;
  GtkTreeModel *model;
  gint type;
  GtkArbre *garbre = data;

  if (gtk_tree_selection_get_selected (selection, &model, &iter))
    {
      gtk_tree_model_get (model, &iter,
			  TYPE_COLUMN, &type,
			   -1);
      if(type == REGROUPEMENT_OEU)
	{
	  Arbre *arb;
	  /*	  arb = recupSousArbreId_Arb(arbre, id);*/
	  gtk_tree_model_get (model, &iter, 
			      ARBRE_COLUMN, &arb,
			      -1);

	  setInfoRegroupement_GInf(garbre->gInfo, arb);
	}
      else if(type == VIDE_OEU)
	{
	  setInfoVide_GInf(garbre->gInfo);
	}
      else
	{
	  Oeuvre *oeuvre = NULL;
	  gtk_tree_model_get (model, &iter,
			      ARBRE_COLUMN, &oeuvre,
			      -1);
	  if(oeuvre)
	    {
	      setInfoOeuvre_GInf(garbre->gInfo, oeuvre);
	    }
	}
    }
}

void removeIterChild(GtkArbre *gArbre, GtkTreeIter *iter)
{
  GtkTreeIter iterEnfant;
  /* Récupère le premier enfant de iter */
  if(gtk_tree_model_iter_children(gtk_tree_view_get_model(GTK_TREE_VIEW(gArbre->gArbre)), &iterEnfant, iter))
    /* Tant que l'iter enfant est valide, on le supprimer et on passe au suivant */
    while(gtk_tree_store_iter_is_valid(gArbre->store, &iterEnfant))
      gtk_tree_store_remove(gArbre->store, &iterEnfant);
}

void expanded(GtkTreeView *tree_view, GtkTreeIter *iter, GtkTreePath *path, gpointer user_data)
{
  GtkArbre *gArbre = user_data;
  Arbre * arb;
  int id;
  GtkTreeIter iterEnfant;
  GtkTreeModel *model = gtk_tree_view_get_model(tree_view);
  /* Récupération de l'id de la ligne qui s'ouvre */
  gtk_tree_model_get(model, iter, ID_COLUMN, &id, -1);
  /* Récupération de l'arbre associé */
  gtk_tree_model_get (model, iter, 
		      ARBRE_COLUMN, &arb,
		      -1);
  if(estVide_Arb(arb) == 1)
    {
      /* Récupération des sous arbres */
      recuperation_DReg(arb, id, 1);
      /* Récupération des feuilles */
      recuperation_DOeu(arb, id);
      /* Insertion dans l'arbre de gtk */
      recuperation_Arbre_GArb(gArbre->store, arb, iter, 1);
      /* En fonction du nombre d'enfant */
      if(gtk_tree_model_iter_n_children(model, iter) != 1)
	{
	  /* On supprime le premier qui est là juste pour afficher l'expand */
	  if(gtk_tree_model_iter_children(model, &iterEnfant, iter))
	    gtk_tree_store_remove(gArbre->store, &iterEnfant);
	}
      else
	{
	  /* On modifie le premier pour mettre le titre à vide */
	  if(gtk_tree_model_iter_children(model, &iterEnfant, iter))
	    gtk_tree_store_set (gArbre->store, &iterEnfant,
				TITRE_COLUMN, "vide",
				TYPE_COLUMN, VIDE_OEU,
				-1);
	}
    }
  (void)path;
}

void collapsed(GtkTreeView *tree_view, GtkTreeIter *iter, GtkTreePath *path, gpointer user_data)
{
  GtkArbre *gArbre = user_data;
  GtkTreeIter iterEnfant;
  Arbre *arb;
  /* On supprime tout les enfants */
  removeIterChild(gArbre, iter);
  /* On récupère l'id de la ligne qui se ferme */
  gtk_tree_model_get(gtk_tree_view_get_model(tree_view), iter,
		     ARBRE_COLUMN, &arb, -1);
  vider_Arb(arb);
  /* On ajoute une ligne pour afficher l'expande */
  gtk_tree_store_append(gArbre->store, &iterEnfant, iter);
  (void)path;
}

void detruire_GArb(GtkArbre **gArbre)
{
  if(gArbre)
    {
      if((*gArbre))
	{
	  Arbre *arb;
     	  arb = (*gArbre)->arbre;
	  if(arb)
	    detruire_Arb(&arb);
	  free((*gArbre));
	}
    }
}

GtkWidget * getContainer_GArb(GtkArbre *arbre)
{
  return arbre->scroll;
}

void recuperation_Arbre_GArb(GtkTreeStore *store, Arbre *arbre, GtkTreeIter *iterPere, int level)
{
  if(level)
    {
      GtkTreeIter iter;
      Ensemble *ensembleReg, *ensembleOeu;
      int tailleReg, i;
      ensembleReg = recupSousArbre_Arb(arbre);
      tailleReg = getTaille_Ens(ensembleReg);
      prems_Ens(ensembleReg);
      for(i = 0; i < tailleReg; i++)
	{
	  GtkTreeIter iterEnfant;

	  gtk_tree_store_append(store, &iter, iterPere);
	  gtk_tree_store_set (store, &iter,
			      TITRE_COLUMN, getTitre_Reg(getInformation(getData_Ens(ensembleReg))),
			      TYPE_COLUMN, REGROUPEMENT_OEU,
			      ID_COLUMN, getId_Reg(getInformation(getData_Ens(ensembleReg))),
			      ARBRE_COLUMN, getData_Ens(ensembleReg),
			      -1);
	  gtk_tree_store_append(store, &iterEnfant, &iter);
	  gtk_tree_store_set (store, &iterEnfant,
			      TITRE_COLUMN, "vide",
			      TYPE_COLUMN, VIDE_OEU,
			      -1);
	  recuperation_Arbre_GArb(store, getData_Ens(ensembleReg), &iter, level -1);

	  suivant_Ens(ensembleReg);
	}
      ensembleOeu = recupFeuille_Arb(arbre);
      tailleReg = getTaille_Ens(ensembleOeu);
      prems_Ens(ensembleOeu);
      for(i = 0; i < tailleReg; i++)
	{
	  gtk_tree_store_append(store, &iter, iterPere);
	  gtk_tree_store_set (store, &iter,
			      VUE_COLUMN, (getNbVisio_Oeu(getData_Ens(ensembleOeu)) > 0 ? TRUE : FALSE),
			      TITRE_COLUMN, getTitre_Oeu(getData_Ens(ensembleOeu)),
			      TYPE_COLUMN, getType_Oeu(getData_Ens(ensembleOeu)),
			      ID_COLUMN, getId_Oeu(getData_Ens(ensembleOeu)),
			      ARBRE_COLUMN, getData_Ens(ensembleOeu),
			      -1);
	  suivant_Ens(ensembleOeu);
	}
    }
}
